package com.dsteiner.widgets.client.controller;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import com.dsteiner.widgets.client.Widgets.TextInput;
import com.dsteiner.widgets.client.model.PrefilledTextBoxModel;
import com.dsteiner.widgets.client.resources.WidgetsResources;
import com.dsteiner.widgets.client.text.RichTextAreaExt;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DeferredCommand;

public class TextBoxController{

	public static final String STYLE_NAME_DEFAULT_TEXT = "default-text";
	private PrefilledTextBoxModel prefilledTextBoxModel;
	private TextInput textBox;

	public void registerPrefilledTextBoxModel(final PrefilledTextBoxModel prefilledTextBoxModel) {
		this.prefilledTextBoxModel = prefilledTextBoxModel;
		prefilledTextBoxModel.addPropertyChangeListener("text", new PropertyChangeListener(){
			public void propertyChange(PropertyChangeEvent evt) {
				updateText();
				updateIsEdited();
			}
		});
		prefilledTextBoxModel.addPropertyChangeListener("hasFocus", new PropertyChangeListener(){
			public void propertyChange(PropertyChangeEvent evt) {
				updateHasFocus();
			}
		});
		prefilledTextBoxModel.addPropertyChangeListener("hasError", new PropertyChangeListener(){
			public void propertyChange(PropertyChangeEvent evt) {
				updateStylename();
			}
		});
	}

	public void registerTextBox(final TextInput prefilledTextBox) {
		this.textBox = prefilledTextBox;

		prefilledTextBox.addFocusHandler(new FocusHandler(){
			public void onFocus(FocusEvent event) {
				prefilledTextBoxModel.setHasFocus(true);
			}
		});
		prefilledTextBox.addKeyUpHandler(new KeyUpHandler(){
			public void onKeyUp(KeyUpEvent event) {
				String text = prefilledTextBox.getText();
				prefilledTextBoxModel.setText(text);
				int keyCode = event.getNativeEvent().getKeyCode();
				prefilledTextBoxModel.setKeyCode(keyCode);
			}
		});
		prefilledTextBox.addBlurHandler(new BlurHandler(){
			public void onBlur(BlurEvent event) {
				prefilledTextBoxModel.setHasFocus(false);
			}
		});
	}

	private void updateHasFocus() {
		if(!(textBox instanceof RichTextAreaExt))
			textBox.setFocus(prefilledTextBoxModel.hasFocus());
		if(prefilledTextBoxModel.hasFocus()){
			DeferredCommand.addCommand(new Command(){
				public void execute() {
					if(!prefilledTextBoxModel.isEdited()){
						textBox.setCursorPos(0);
						prefilledTextBoxModel.setText("");
					}
					textBox.selectAll();
				}
			});
		}
		else{
			String text = textBox.getText();
			if(textBox instanceof RichTextAreaExt && "<br>".equalsIgnoreCase(text))
				text = "";
			
			prefilledTextBoxModel.setText(text);
		}
	}

	private void updateIsEdited() {
		String text = prefilledTextBoxModel.getText();
		String defaultText = prefilledTextBoxModel.getDefaultText();
		boolean isEdited = text != null && !text.equals("") && !text.equals(defaultText);
		prefilledTextBoxModel.setEdited(isEdited);
	}

	private void updateStylename() {
		boolean hasError = prefilledTextBoxModel.hasError();
		String styleName = textBox.getStyleName();
		String errorStylename = WidgetsResources.INSTANCE.css().error();
		if(styleName.indexOf(errorStylename) == -1 && hasError)
			textBox.addStyleName(errorStylename);
		else if(styleName.indexOf(errorStylename) != -1 && !hasError)
			textBox.removeStyleName(errorStylename);
			
	}

	private void updateText() {
		String text = prefilledTextBoxModel.getText();
		if(!textBox.getText().equals(text))
			textBox.setText(text);
	}

}
